package com.lan.model.symbol;

import com.lan.model.Type;
import com.lan.model.type.DefaultFunctionType;
import com.lan.model.type.FunctionType;
import org.antlr.v4.runtime.ParserRuleContext;

import java.util.LinkedList;
import java.util.List;

public class Function extends Scope implements FunctionType {
    // 参数
    protected List<Variable> parameters = new LinkedList<>();

    //返回值
    protected List<Type> returnTypes;

    protected List<Type> paramTypes;

    public Function(String name, Scope scope, String id, ParserRuleContext ctx) {
        this.name = name;
        this.scope = scope;
        this.id = id + "_function_" + name;
        this.ctx = ctx;
    }


    public List<Type> getReturnTypes() {
        return returnTypes;
    }

    public void setReturnTypes(List<Type> returnTypes) {
        this.returnTypes = returnTypes;
    }

    @Override
    public List<Type> getParamTypes() {
        if (paramTypes == null) {
            paramTypes = new LinkedList<>();
        }
        for (Variable param : parameters) {
            paramTypes.add(param.type);
        }
        return paramTypes;
    }


    @Override
    public String toString() {
        return "Function " + name;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public Scope getScope() {
        return scope;
    }

    @Override
    public boolean isType(Type type) {
        if (type instanceof FunctionType) {
            return DefaultFunctionType.isType(this, (FunctionType) type);
        }
        return false;
    }

    /**
     * 检查改函数是否匹配所需的参数。
     *
     * @param paramTypes
     * @return
     */
    @Override
    public boolean matchParameterTypes(List<Type> paramTypes) {
        // 比较每个参数
        if (parameters.size() != paramTypes.size()) {
            return false;
        }

        boolean match = true;
        for (int i = 0; i < paramTypes.size(); i++) {
            Variable var = parameters.get(i);
            Type type = paramTypes.get(i);
            if (!var.type.isType(type)) {
                match = false;
                break;
            }
        }

        return match;
    }

    /**
     * 该函数是不是类的方法
     *
     * @return
     */
    public boolean isMethod() {
        return scope instanceof Clazz;
    }

    /**
     * 该函数是不是类的构建函数
     *
     * @return
     */
    public boolean isConstructor() {
        if (scope instanceof Clazz) {
            return name.equalsIgnoreCase(scope.getName());
        }
        return false;
    }


    public List<Variable> getParameters() {
        return parameters;
    }


    public void setParamTypes(List<Type> paramTypes) {
        this.paramTypes = paramTypes;
    }
}